package com.firefly.netty.demo;

import com.firefly.util.utils.JsonUtil;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.ReferenceCountUtil;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.net.InetSocketAddress;

/**
 * @description:
 * @author: lzg(萤火科技 ： 854378082 @ qq.com)
 * @date: 2022/9/16
 **/
@Slf4j
public class NettyClientHandler extends ChannelInboundHandlerAdapter {
    private DataFrame responseResult;

    public void setResponseResult(DataFrame responseResult) {
        this.responseResult = responseResult;
    }

    public DataFrame getResponseResult() {
        return this.responseResult;
    }

    /**
     * 从服务端收到新的数据时，这个方法会在收到消息时被调用
     *
     * @param ctx
     * @param msg
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception, IOException
    {
    	log.debug("channelRead:read msg:"+msg.toString());
        this.responseResult = JsonUtil.str2Obj(msg.toString(),DataFrame.class);
        //回应服务端
        // ctx.write("I got server message thanks server!");
        // 释放资源
        ReferenceCountUtil.release(msg);
        // 主动关闭连接
        ctx.close();
    }

    /**
     * 从服务端收到新的数据、读取完成时调用
     *
     * @param ctx
     */
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws IOException
    {
    	log.debug("channelReadComplete");
    	ctx.flush();
    }

    /**
     * 当出现 Throwable 对象才会被调用，即当 Netty 由于 IO 错误或者处理器在处理事件时抛出的异常时
     *
     * @param ctx
     * @param cause
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws IOException
    {
    	log.debug("exceptionCaught");
        cause.printStackTrace();
        ctx.close();//抛出异常，断开与客户端的连接
    }

    /**
     * 客户端与服务端第一次建立连接时 执行
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception, IOException
    {
        super.channelActive(ctx);
        InetSocketAddress insocket = (InetSocketAddress) ctx.channel().remoteAddress();
        String clientIp = insocket.getAddress().getHostAddress();
        log.debug("channelActive:"+clientIp+ctx.name());
    	/*ByteBuf message = null;
    	byte[] req = ("I am client once").getBytes();
    	for(int i = 0; i < 5; i++) {
    		message = Unpooled.buffer(req.length);
    		message.writeBytes(req);
    		Thread.sleep(5000);
    		ctx.writeAndFlush(message);
    	}*/
    }

    /**
     * 客户端与服务端 断连时 执行
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception, IOException
    {
        super.channelInactive(ctx);
        InetSocketAddress insocket = (InetSocketAddress) ctx.channel().remoteAddress();
        String clientIp = insocket.getAddress().getHostAddress();
        ctx.close(); //断开连接时，必须关闭，否则造成资源浪费
        log.debug("channelInactive:"+clientIp);
    }
}
